package com.gusto.engine.repository.service.impl;

import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.gusto.engine.beans.exceptions.ResCreationException;
import com.gusto.engine.beans.model.Res;
import com.gusto.engine.repository.dao.RepositoryDAO;
import com.gusto.engine.repository.exception.RepositoryException;
import com.gusto.engine.repository.params.Param;
import com.gusto.engine.repository.service.RepositoryService;
import com.opensymphony.oscache.base.Cache;
import com.opensymphony.oscache.general.GeneralCacheAdministrator;

/**
 * <p>Implements the {@link RepositoryService}, 
 * by delegating the access to the {@link TestDatabaseJpaRepositoryDAO},
 * and implementing a Cache mechanism.</p>
 * 
 * @author amokrane.belloui@gmail.com
 */
public class RepositoryServiceImpl implements RepositoryService {
	
	private Logger log = Logger.getLogger(getClass());
	
	private GeneralCacheAdministrator cacheAdministrator;
	private Cache cache;
	private RepositoryDAO repositoryDAO;
	
	public RepositoryServiceImpl() {
		super();
		Properties props = new Properties();
		props.put("cache.memory", true);
		props.put("cache.capacity", "10000");
		props.put("cache.unlimited.disk", true);
		props.put("cache.algorithm", "com.opensymphony.oscache.base.algorithm.LRUCache");
		cacheAdministrator = new GeneralCacheAdministrator(props); 
		this.cache = cacheAdministrator.getCache();
	}
	
	/**
	 * Sets the size of the cache
	 * @param cache_size
	 */
	public void setCACHE_SIZE(String cache_size) {
		cacheAdministrator.setCacheCapacity(Integer.parseInt(cache_size));
		log.info("Cache size set to : " + this.cache.getCapacity());
	}
	
	/**
	 * Sets the ResDAO implementation
	 * @param repositoryDAO
	 */
	public void setRepositoryDAO(RepositoryDAO repositoryDAO) {
		this.repositoryDAO = repositoryDAO;
	}
	
	/**
	 * {@inheritDoc}
	 */
	public Res getResource(Object... resource) throws ResCreationException, RepositoryException {
		String key = resource.toString();
		Res res;
		try {
			res = (Res) cache.getFromCache(key);
			log.info("Getting Res from Cache");
		} 
		catch (com.opensymphony.oscache.base.NeedsRefreshException nre) {
			res = this.repositoryDAO.getResource(resource);
			cache.putInCache(key, res);
			log.info("Getting Res with no cache");
		}
		return this.repositoryDAO.getResource(resource);
	}
	
	/**
	 * {@inheritDoc}
	 */
	public List<Res> query(String queryString, Param[] queryParams, Object... params) throws ResCreationException, RepositoryException {
		log.info("Querying with no cache");
		return this.repositoryDAO.query(queryString, queryParams, params);
	}

	/**
	 * Destroy the RepositoryService, by destroying the cache
	 */
	public void destroy() {
		cacheAdministrator.destroy();
	}
	
}
